
/**
 * 请求头user-agent
 * 
 * @author jn
 */
export class UserAgentUtils {

    operatingSystems = {
        "iPad": /ipad/i
        , "iPhone": /iphone/i
        , "Windows Vista": /windows nt 6\.0/i
        , "Windows 7": /windows nt 6\.\d+/i
        , "Windows 2003": /windows nt 5\.2+/i
        , "Windows XP": /windows nt 5\.1+/i
        , "Windows 2000": /windows nt 5\.0+/i
        , "OS X $1.$2": /os x (\d+)[._](\d+)/i
        , "Linux": /linux/i
        , "Googlebot": /googlebot/i
        , "Windows 10": /windows nt 10\.0+/i
    }

    osNames = Object.keys(this.operatingSystems);

    names = [
        "opera"
        , "konqueror"
        , "firefox"
        , "chrome"
        , "epiphany"
        , "safari"
        , "msie"
        , "curl"
    ];

    /**
     * 获取请求头
     * @param str 请求头user-agent
     * @returns 
     */
    parse(str: string = "") {
        let agent = { full: str, name: this.name(str) } as unknown as { version: string, fullName: string, name: string, os: string };
        agent.version = this.version(str, agent.name);
        agent.fullName = agent.name + " " + agent.version;
        agent.os = this.os(str);
        return agent;
    }

    version(str: string = "", name: string = "") {
        if (name === "safari") name = "version";
        if (name) {
            return new RegExp(name + "[\\/ ]([\\d\\w\\.-]+)", "i").exec(str) && RegExp.$1 || "";
        } else {
            let m = str.match(/version[\/ ]([\d\w\.]+)/i);
            return m && m.length > 1 ? m[1] : "";
        }
    }

    os(str: string = "") {
        let captures: any;
        for (let i = 0, len = this.osNames.length; i < len; ++i) {
            if (captures = this.operatingSystems[this.osNames[i]].exec(str)) {
                return ~this.osNames[i].indexOf("$1")
                    ? this.osNames[i].replace(/\$(\d+)/g, function (_, n) {
                        return captures[n]
                    }) : this.osNames[i];
            }
        }
        return "";
    }

    name(str: string = "") {
        str = str.toLowerCase();
        for (let i = 0, len = this.names.length; i < len; ++i) {
            if (str.indexOf(this.names[i]) !== -1) return this.names[i];
        }
        return "";
    }

}